#ifndef CPAYMENTMANAGER_H_
#define CPAYMENTMANAGER_H_

#include <iostream>
#include <mutex>

#include "CommonType.h"

namespace zl {

/// \brief 付费方案接口
class CPaymentPlan
{
public:
    CPaymentPlan();
    ~CPaymentPlan() = default;

    inline int32_t id() const { return id_; }
    inline void set_id(int32_t id) { id_ = id; }
    inline std::string alias() const { return alias_; }
    inline void set_alias(const std::string& alias) { alias_ = alias; }
    inline bool is_free() const { return isfree_ == 1; }
    inline void set_free(bool flag) { isfree_ = flag ? 1 : 0; }
    inline int32_t prepaid() const { return prepaid_; }
    inline void set_prepaid(int32_t value) { prepaid_ = value; }
    inline int32_t prepaid_amount() const { return prepaid_amount_; }
    inline void set_prepaid_amount(int32_t value) { prepaid_amount_ = value; }
    inline int32_t trail_duration() const { return trail_duration_; }
    inline void set_trail_duration(int32_t value) { trail_duration_ = value; }
    inline int32_t billing_period() const { return billing_period_; }
    inline void set_billing_period(int32_t value) { billing_period_ = value; }
    inline int32_t billing_price() const { return billing_price_; }
    inline void set_billing_price(int32_t value) { billing_price_ = value; }
    inline int32_t billing_caps() const { return billing_caps_; }
    inline void set_billing_caps(int32_t value) { billing_caps_ = value; }
    inline int32_t billing_unit() const { return billing_unit_; }
    inline void set_billing_unit(int32_t value) { billing_unit_ = value; }
    inline bool need_overdue_charge() const { return need_overdue_charge_ == 1; }
    inline void set_need_overdue_charge(bool flag) { need_overdue_charge_ = flag ? 1 : 0; }

    /// 根据订单信息中的使用信息计算费用
    int32_t calculate_cost(const zl::Order& order);

protected:
    /// 获取当前预付费设置的金额
    int32_t calculate_get_prepaid_amount();
    /// 按天收费
    int32_t calculate_by_hours(const std::string& begtime);
    /// 按小时收费
    int32_t calculate_by_days(const std::string& begtime);

private:
    std::string alias_;          ///< 别名
    int32_t id_;                 ///< 编号
    int32_t isfree_;             ///< 是否免费使用（1：免费，0：不免费）
    int32_t prepaid_;            ///< 是否需要预付费 (1: 需要，0：不需要）
    int32_t prepaid_amount_;     ///< 预付费金额（单位为当前币种最小金额）
    int32_t trail_duration_;     ///< 免费试用时长，当实际试用时间超过免费是试用时长时会额外收费
    int32_t need_overdue_charge_;   ///< 是否需要超期收费
    int32_t billing_unit_;       ///< 计费单位的类型（0：小时，1：天）
    int32_t billing_period_;     ///< 收费周期
    int32_t billing_price_;      ///< 每周期费用（即每使用满一个周期，产生一次费用）
    int32_t billing_caps_;       ///< 收费周期限额（及最多收取的周期的数量）
};

/// \brief 付费管理接口
/// \note 用来创建/修改付费方案，并能通过接受订单信息，返回应收取的费用
class CPaymentManager
{
public:
    static CPaymentManager* Instance();
    static void Release();

    int32_t Initialized();
    int32_t Uninitialized();

    /// \brief 根据订单信息计算订单费用信息
    int32_t Calculate(int32_t planid, const zl::Order& order);

    /// \brief 返回指定付费方案中的免费时长信息
    std::string GetTrailDuration(int32_t planid);

    /// \brief 创建新的收费方案，并保存到数据库中
    int32_t CreatePaymentPlan(const CPaymentPlan& plan);

    /// \brief 更新收费方案，更新以有的收费方案
    int32_t UpdatePaymentPlan(const CPaymentPlan& plan);

    /// \brief 删除收费方案
    int32_t DeletePaymentPlan(int32_t id);

    /// \brief 查询收费方案
    int32_t RetrievePaymentPlan(int32_t id, CPaymentPlan& plan);
    int32_t RetrievePaymentPlan(std::vector<CPaymentPlan>& planlist);

    /// \brief 添加支付记录
    int32_t CreatePaidDetails(const zl::PaidDetail& details);

    /// \brief 更新支付记录
    int32_t UpdatePaidDetails(const zl::PaidDetail& details);

    /// \brief 删除支付记录
    int32_t DeletePaidDetails(const std::string& paid_orderid);

    /// \brief 查询支付记录
    int32_t RetrievePaidDetails(std::vector<zl::PaidDetail>& detailslist);

    /// \brief 根据时间和支付方式查询支付记录
    int32_t RetrievePaidDetails(
        std::vector<zl::PaidDetail>& detailslist,
        const std::string& begin_time, const std::string& end_time,
        const std::string& type);

    /// \brief 确认支付记录
    int32_t ConfirmPaidDetails(const std::string& paid_orderid);

    /// \brief 获取所有未确认的支付记录信息
    int32_t RetrieveAllUnconfirmedPaidDetails(std::vector<zl::PaidDetail>& detailslist);

protected:
    CPaymentManager() = default;
    ~CPaymentManager() = default;

    int32_t load_data(std::vector<CPaymentPlan>& planlist);

private:
    static CPaymentManager* instance_;

    std::mutex mutex_;
    std::vector<CPaymentPlan> plan_list_;
};

}

#endif // CPAYMENMANAGER_H_
